/**
 * 
 */
package edu.pw.treegrid.server.classmodel;

import java.util.HashSet;
import java.util.Set;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import edu.pw.treegrid.server.service.XMLMarshaller;
import xalan.xml.XMLUtils;

/** 
 * @author Xalan
 */
public class DomainClass {

	public static final String CLASS_ELEMENT = "class";
	public static final String REF_ELEMENT = "ref";
	public static final String ATTRIBUTES_ELEMENT = "attributes";
	public static final String TABLE_NAME_ELEMENT = "tableName";
	public static final String PRIMARY_ATTRIBUTE_ELEMENT = "primaryAttribute";
	public static final String NAME_ELEMENT = "name";
	public static final String ID_ATTRIBUTE_NAME = "id";
	
	private String primaryAttributeId;
	
	private String id;

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	private String name;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	private String tableName;

	public String getTableName() {
		return tableName;
	}

	public void setTableName(String tableName) {
		this.tableName = tableName;
	}

	private Set<DomainAttribute> attributes = new HashSet<DomainAttribute>();

	public Set<DomainAttribute> getAttributes() {
		return attributes;
	}

	private SimpleAttribute primaryAttribute;

	public SimpleAttribute getPrimaryAttribute() {
		return primaryAttribute;
	}

	public void setPrimaryAttribute(SimpleAttribute primaryAttribute) {
		this.primaryAttribute = primaryAttribute;
	}

	public void addAttribute(DomainAttribute attribute) {
		this.attributes.add(attribute);
		attribute.setDomainClass(this);
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((id == null) ? 0 : id.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		DomainClass other = (DomainClass) obj;
		if (id == null) {
			if (other.id != null)
				return false;
		} else if (!id.equals(other.id))
			return false;
		return true;
	}
	
	public Element serializeToXML(Document document) {
		Element classElement = document.createElement(CLASS_ELEMENT);
		
		classElement.setAttribute(ID_ATTRIBUTE_NAME, this.id);
		
		XMLUtils.newElement(document, classElement, NAME_ELEMENT, this.name);
		
		Element primaryAttributeElement = document.createElement(PRIMARY_ATTRIBUTE_ELEMENT);
		primaryAttributeElement.setAttribute(REF_ELEMENT, primaryAttribute.getId());
		classElement.appendChild(primaryAttributeElement);

		XMLUtils.newElement(document, classElement, TABLE_NAME_ELEMENT, this.tableName);
		
		Element attributesElement = document.createElement(ATTRIBUTES_ELEMENT);
		classElement.appendChild(attributesElement);
		for(DomainAttribute a : attributes) {
			attributesElement.appendChild(a.serializeToXML(document));
		}

		return classElement;
	}

	public void deserializeFromXML(Element e) {
		this.id = e.getAttribute(ID_ATTRIBUTE_NAME);
		this.name = XMLUtils.getElementsText(e, NAME_ELEMENT);
		this.tableName = XMLUtils.getElementsText(e, TABLE_NAME_ELEMENT);
		this.attributes = new HashSet<DomainAttribute>();
		this.primaryAttributeId = XMLUtils.getAttributeText(XMLUtils.getFirstElement(e, PRIMARY_ATTRIBUTE_ELEMENT), REF_ELEMENT);
		
		NodeList attributesList = e.getElementsByTagName(DomainAttribute.ATTRIBUTE_ELEMENT);
		for(int i=0;i<attributesList.getLength();++i) {
			Element ae = (Element)attributesList.item(i);
			DomainAttribute da = DomainAttribute.newAttribute(ae);
			addAttribute(da);
		}
	}

	public void setReferences(XMLMarshaller xmlMarshaller) {
		this.primaryAttribute = (SimpleAttribute)xmlMarshaller.getAttributeById(primaryAttributeId);
	}

	@Override
	public String toString() {
		return name;
	}

}